

# Create your views here.
"""
一 把需求写下来 (前端需要收集什么 后端需要做什么)

    前端需要生成一个随机码(uuid), 把这个随机码给后端

    后端需要生成图片验证码,把这个图片验证码的内容保存到redis中 redis的数据是
    uuid: xxxx  有有效期
二 把大体思路写下来(后端的大体思路)
    1.生成图片验证码和获取图片验证码的内容
    2.连接redis,将 图片验证码保存起来 uuid:xxxx 有有效期
    3.返回图片验证码

三 把详细思路完善一下(纯后端)

    1.生成图片验证码和获取图片验证码的内容
    2.1连接redis,
    2.2将 图片验证码保存起来 uuid:xxxx 有有效期
    3.返回图片验证码


四 确定我们请求方式和路由

    GET     image_codes/(?P<uuid>[\w-]+)/

    GET     image_codes/?uuid=xxxxx
"""
import random

from django.views import View
from libs.captcha.captcha import captcha
from django_redis import get_redis_connection
from django.http import HttpResponse

from libs.yuntongxun.sms import CCP
from utils.response_code import RETCODE
from . import constants
from django import http

from .constants import SMS_CODE_EXPIRE_TIME


class ImageCodeView(View):

    def get(self, request, uuid):
        # 1.生成图片验证码和获取图片验证码的内容
        text, image = captcha.generate_captcha()
        # 2.1 连接redis,
        red_conn = get_redis_connection('code')
        # 2.2 将图片验证码保存起来  uuid: xxxx 有有效期
        red_conn.setex('img_%s'%uuid, constants.IMAGE_CODE_EXPIRE_TIME, text)

        # 3. 返回图片验证码
        return HttpResponse(image, content_type='image/jpeg')


"""
云通讯:
    第一步:
        正式接入步骤：
                注册 》 提交认证 》 充值 》 提交短信模板（免费测试仅需注册）
        测试:
            注册 》免费测试仅需注册


    第二步:
        看文档开发

        1.下载SDK (SDK 可以理解为 django-redis 直接把库(包)安装直接使用 )
        2.修改指定的配置

    第三步：
        验证

用户点击获取短信验证码按钮,我们能够给用户发送短信

一 把需求写下来 (前端需要收集什么 后端需要做什么)
    前端需要收集: 手机号,用户输入的 图片验证码内容 和 UUID
    通过ajax发送给后端
二 把大体思路写下来(后端的大体思路)

    接收参数
    验证参数
    发送短信

三 把详细思路完善一下(纯后端)

    1. 接收参数(手机号,图片验证码,uuid)
    2. 验证参数
        验证手机号
        这三个参数必须有
    3. 验证用户输入的图片验证码和服务器保存的图片验证码一致
        3.1 用户的图片验证码
        3.2 服务器的验证码
        3.3 比对
    4. 先生成一个随机短信码
    5. 先把短信验证码保存起来
        redis key:value
    6. 最后发送


四 确定我们请求方式和路由

    GET
        提取URL的特定部分，如/weather/beijing/2018，可以在服务器端的路由中用正则表达式截取；
            /smscode/mobile/uuid/imagecode/
        查询字符串（query string)，形如key1=value1&key2=value2；
            /smscode/?mobile=xxxx&uuid=xxxx&imagecode=xxxx

        混合的
            /sms_codes/(?P<mobile>1[3-9]\d{9})/?uuid=xxx&imagecode=xxxxx

    POST
"""
import logging

logger = logging.getLogger('django')
class SMSCodeView(View):

    def get(self, request, mobile):
        #         1.接收参数(手机号, 图片验证码, uuid)
        image_code_client = request.GET.get('image_code')
        uuid = request.GET.get('image_code_id')
        #         2.验证参数 验证手机号 这三个参数必须有
        if not all([mobile, image_code_client, uuid]):
            return http.JsonResponse({'code': RETCODE.NECESSARYPARAMERR, 'errmsg': '缺少必要参数'})
        #     3.验证用户输入的图片验证码和服务器保存的图片验证码一致
        try:
            rediscnn = get_redis_connection('code')
            #     3.1用户的图片验证码
            #     3.2 服务器的验证码
            image_code_server = rediscnn.get('img_%s'%uuid)
            #     3.3比对
            # 我们获取redis的数据都是bytes类型
            # 添加一个删除图片验证码的逻辑
            # 1. 删除可以防止 用户再次比对
            # 2. 从redis数据是保存在内存中,不用的就删除,节省内存空间
            if not image_code_server.decode().lower() == image_code_client.lower():
                return http.JsonResponse({"code": RETCODE.IMAGECODEERR, 'errmsg':'图形验证码失效'})
            rediscnn.delete('img_%s'%uuid)
        except Exception as e:
            logger.er(e)
        # 判断标记位是否为1
        send_flag = rediscnn.get('send_flag_%s'%mobile)
        if send_flag:
            return http.response({"code":RETCODE.THROTTLINGERR, "errmsg":"验正码发送过于频繁"})

        # 4. 先生成一个随机短信码
        # sms_code ='%06d'%random.randint(0, 999999)
        sms_code ='%04d'%random.randint(0, 9999)
        # ① 创建管道
        pipe = rediscnn.pipeline()
        # # ②将指令放入管道

        pipe.setex('sms_%s'%mobile, SMS_CODE_EXPIRE_TIME,sms_code)
        pipe.setex('send_flag_%s'%mobile, 60, 1)
        # ③ 让管道执行
        pipe.execute()
        # 5.先把短信验证码保存起来
        # redis
        # key: value
        # rediscnn.setex('sms_%s'%mobile, SMS_CODE_EXPIRE_TIME,sms_code)
        # rediscnn.setex('send_flag_%s'%mobile, 60, 1)
        # 6.
        # 最后发送
        # 6. 最后发送
        # 注意： 测试的短信模板编号为1
        # 参数1: 给谁发
        # 参数２：　【云通讯】您使用的是云通讯短信模板，您的验证码是{1}，请于{2}分钟内正确输入
        # 参数３：　模板号　，默认我们选１
        # CCP().send_template_sms(mobile, [sms_code, 5], 1)
        from celery_tasks.sms.tasks import send_sms_code
        send_sms_code.delay(mobile, sms_code)
        return http.JsonResponse({'code':RETCODE.OK, 'errmsg': '发送短信成功'})